'use strict';
const Sequelize = require('sequelize');
const Op = Sequelize.Op;

module.exports = (app) => {
  class BlogService extends app.Service {
    // 创建博客
    async create() {
      const { app, ctx } = this;
      const { Blog, BlogClassify, User, Classify, Project } =
        app.model.Tables.Blog;
      const data = ctx.request.body;

      // 新建博客
      const res = await Blog.create({
        userId: ctx.userInfo.id,
        userName: ctx.userInfo.name,
        userAvatar: ctx.userInfo.avatar,
        title: data.title,
        content: data.content,
        cover: data.cover,
        projectId: Number(ctx.userInfo.projectId),
      });
      // 用户发布博客数自增1
      await User.findByPk(ctx.userInfo.id).then(function (user) {
        user.increment('blogCount').then(function (user) {
          console.log('success');
        });
      });
      // 如果新建博客成功  根据分类数组长度写入数据库
      if (res.dataValues.id) {
        for (let i = 0; i < data.classifyArr.length; i++) {
          const cRes = await Classify.findByPk(data.classifyArr[i]);
          await BlogClassify.create({
            blogId: res.dataValues.id,
            classifyId: data.classifyArr[i],
            classifyName: cRes.dataValues.classifyName,
            projectId: ctx.userInfo.projectId,
          });
        }
      }
      return res;
    }
    // 获取所有博客
    async getAllBlog() {
      const { app, ctx } = this;
      const { Blog, BlogClassify, LikeBlog } = app.model.Tables.Blog;
      const data = ctx.query;

      // 查找博客
      const res = await Blog.findAndCountAll({
        where: {
          projectId: data.projectId,
        },
        // 降序
        order: [['id', 'DESC']],
        limit: Number(data.limit) || 10,
        offset: Number(data.offset) || 0,
        distinct: true,
        // 联表查找分类
        include: [
          {
            model: BlogClassify,
            attributes: ['classifyId', 'classifyName'],
          },
          // 联表查找点赞的用户
          {
            model: LikeBlog,
            attributes: ['likeUserId'],
          },
        ],
      });
      return res;
    }
    // 根据id查找博客
    async searchById() {
      const { app, ctx } = this;
      const { Blog, BlogClassify, User, History, LikeBlog, Follow } =
        app.model.Tables.Blog;
      const data = ctx.query;

      // 先根据博客id在博客表查询
      const res = await Blog.findOne({
        where: {
          id: data.id,
          projectId: ctx.userInfo.projectId || ctx.adminInfo.project_id,
        },
        order: [['id', 'DESC']],
        // 连表查找该博客分类 点赞记录 作者信息
        include: [
          {
            model: BlogClassify,
            // 字段
            attributes: ['classifyId', 'classifyName'],
          },
          {
            model: LikeBlog,
            attributes: ['likeUserId'],
          },
        ],
      });

      // 如果博客存在
      if (res) {
        // 获取作者粉丝信息
        const fRes = await Follow.findAndCountAll({
          where: {
            beFollowUserId: res.dataValues.userId,
          },
        });

        res.follow = fRes;
        // 博客浏览量数自增1
        await Blog.findByPk(data.id).then(function (blog) {
          blog.increment('read_count').then(function (blog) {
            console.log('success');
          });
        });
        // 如果已登录
        if (ctx.userInfo) {
          // 先去历史记录表查询用户是否已浏览过 没浏览过则生成历史记录
          const HRes = await History.findOrCreate({
            where: {
              userId: ctx.userInfo.id,
              blogId: data.id,
              projectId: ctx.userInfo.projectId || ctx.adminInfo.project_id,
            },
          });
          // 如果HRes[1]为true说明未浏览过
          if (HRes[1]) {
            // 如果用户已登录则浏览历史自增1
            if (ctx.userInfo) {
              // 用户浏览历史数自增1
              await User.findByPk(ctx.userInfo.id).then(function (user) {
                user.increment('historyCount').then(function (user) {
                  console.log('success');
                });
              });
            }
          }
          // 浏览过则更新历史记录时间
          else {
            await History.update(
              { userId: ctx.userInfo.id },
              {
                where: {
                  userId: ctx.userInfo.id,
                  blogId: data.id,
                },
              }
            );
          }
        }
      }
      return res;
    }
    // 根据分类id查找博客
    async searchByClassifyId() {
      const { app, ctx } = this;
      const { BlogClassify, Blog, LikeBlog } = app.model.Tables.Blog;
      const data = ctx.query;

      // 查找分类所属博客
      const res = await BlogClassify.findAndCountAll({
        where: {
          classifyId: data.id,
          projectId: data.projectId,
        },
        order: [['id', 'DESC']],
        limit: Number(data.limit) || 10,
        offset: Number(data.offset) || 0,
        attributes: { exclude: ['id'] },
      });
      // 根据返回结果查找点赞的人和博客信息
      for (let i = 0; i < res.rows.length; i++) {
        const Bres = await Blog.findOne({
          where: {
            id: res.rows[i].blogId,
            projectId: data.projectId,
          },
          attributes: { exclude: ['id'] },
        });
        // 博客信息
        if (Bres) {
          res.rows[i].dataValues.Blog = Bres.dataValues;
        }
        // 点赞的人
        const LRes = await LikeBlog.findAndCountAll({
          order: [['id', 'DESC']],
          where: {
            blogId: res.rows[i].blogId,
          },
          attributes: ['likeUserId'],
        });
        res.rows[i].dataValues.LikeBlog = LRes;
      }

      return res;
    }
    // 根据关键词搜索博客
    async searchByInput() {
      const { app, ctx } = this;
      const { Blog } = app.model.Tables.Blog;
      const data = ctx.query;

      /** 根据标题模糊查询 */
      const titleRes = await Blog.findAll({
        where: {
          title: { [Op.like]: '%' + data.keyword + '%' },
          projectId: data.projectId,
        },
      });
      /** 根据内容模糊查询 */
      const contentRes = await Blog.findAll({
        where: {
          content: { [Op.like]: '%' + data.keyword + '%' },
          projectId: data.projectId,
        },
      });
      const allRes = titleRes.concat(contentRes);
      // 去重
      const res = allRes.reduce((prev, cur) => {
        const id = prev.map((item) => {
          return item.id;
        });
        return id.includes(cur.id) ? prev : [...prev, cur];
      }, []);
      return res;
    }
    // 获取用户自己的博客
    async getMyBlog() {
      const { app, ctx } = this;
      const { Blog, BlogClassify, Classify } = app.model.Tables.Blog;
      const data = ctx.query;

      // 查找用户自己文章
      const res = await Blog.findAndCountAll({
        where: {
          userId: ctx.userInfo.id,
          projectId: data.projectId,
        },
        limit: Number(data.limit) || 10,
        offset: Number(data.offset) || 0,
        // 使count为第一层的数量
        distinct: true,
        include: {
          // 表名
          model: BlogClassify,
          // 字段
          attributes: ['classifyId'],
        },
      });

      // 根据连表查找到分类id 再根据分类id查询分类名
      for (let i = 0; i < res.rows.length; i++) {
        const arr = res.rows[i].BlogClassifies;
        if (arr) {
          for (let j = 0; j < arr.length; j++) {
            const classifyRes = await Classify.findByPk(arr[j].classifyId);
            arr[j].dataValues.classifyName = classifyRes.classifyName;
          }
        }
      }
      return res;
    }
    // 更新修改博客
    async updateBlog() {
      const { app, ctx } = this;
      const { Blog, BlogClassify, Classify } = app.model.Tables.Blog;
      const data = ctx.request.body;
      // 查询文章作者
      const finsRes = await Blog.findByPk(data.id);

      if (!finsRes.dataValues) {
        return '博客id不存在';
      }
      // 判断是否作者操作
      if (finsRes.dataValues.userId == ctx.userInfo.id) {
        // 更新标题和内容
        const res = await Blog.update(
          {
            title: data.title,
            content: data.content,
            cover: data.cover,
          },
          {
            where: {
              id: data.id,
              projectId: data.projectId,
            },
          }
        );
        // 删除原来的分类
        await BlogClassify.destroy({
          where: {
            blogId: data.id,
            projectId: data.projectId,
          },
        });
        // 如果修改博客成功  根据分类数组长度写入数据库
        if (res) {
          for (let i = 0; i < data.classifyArr.length; i++) {
            const cRes = await Classify.findByPk(data.classifyArr[i]);
            if (cRes) {
              await BlogClassify.create({
                blogId: data.id,
                classifyId: data.classifyArr[i],
                classifyName: cRes.dataValues.classifyName,
                projectId: data.projectId,
              });
            }
          }
        }
        return '修改成功';
      }
      return '您不是文章作者';
    }
    // 删除博客
    async deleteBlog() {
      const { app, ctx } = this;
      const { Blog, BlogClassify, User } = app.model.Tables.Blog;
      const data = ctx.request.body;
      // 查询文章作者
      const findRes = await Blog.findOne({
        where: {
          id: data.id,
        },
      });

      if (!findRes.dataValues) {
        return '博客id不存在';
      }
      // 判断是否作者操作
      if (findRes.dataValues.userId == ctx.userInfo.id) {
        // 删除博客
        await Blog.destroy({
          where: {
            id: data.id,
            projectId: data.projectId,
          },
        });
        // 删除博客所属分类
        await BlogClassify.destroy({
          where: {
            blogId: data.id,
            projectId: data.projectId,
          },
        });
        // 作者博客数自减1
        await User.findByPk(findRes.dataValues.userId).then(function (user) {
          user.decrement('blogCount').then(function (user) {
            console.log('success');
          });
        });

        return '删除成功';
      }
      return '您不是文章作者';
    }

    // 点赞博客
    async likeBlog() {
      const { app, ctx } = this;
      const { Blog, User, LikeBlog } = app.model.Tables.Blog;
      const data = ctx.request.body;
      // 查询是否已点赞
      const res = await LikeBlog.findOne({
        where: {
          blogId: data.id,
          likeUserId: ctx.userInfo.id,
          projectId: data.projectId,
        },
      });
      if (res) {
        // 取消点赞
        await LikeBlog.destroy({
          where: {
            blogId: data.id,
            likeUserId: ctx.userInfo.id,
            projectId: data.projectId,
          },
        });
        // 博客点赞数自减1 如果博客id不存在 直接抛出错误
        await Blog.findByPk(data.id).then(function (blog) {
          blog.decrement('like_count').then(function (blog) {
            console.log('success');
          });
        });
        // 用户点赞量自减1
        await User.findByPk(ctx.userInfo.id).then(function (user) {
          user.decrement('likeCount').then(function (user) {
            console.log('success');
          });
        });
        return '取消点赞成功';
      }
      // 验证博客id
      const blogRes = await Blog.findByPk(data.id);
      if (blogRes) {
        // 如果res不为null则已点赞
        // res为null则未点赞
      } else {
        return '博客id不存在';
      }
      // 点赞
      await LikeBlog.create({
        blogId: data.id,
        likeUserId: ctx.userInfo.id,
        projectId: data.projectId,
      });
      // 博客点赞数自增1 如果博客id不存在 直接抛出错误
      await Blog.findByPk(data.id).then(function (blog) {
        blog.increment('like_count').then(function (blog) {
          console.log('success');
        });
      });
      // 用户点赞量自增1
      await User.findByPk(ctx.userInfo.id).then(function (user) {
        user.increment('likeCount').then(function (user) {
          console.log('success');
        });
      });
      return '点赞成功';
    }

    // 获取浏览博客历史
    async getHistory() {
      const { app, ctx } = this;
      const { Blog, History, LikeBlog } = app.model.Tables.Blog;
      const data = ctx.query;
      const res = await History.findAndCountAll({
        where: {
          userId: ctx.userInfo.id,
          projectId: data.projectId,
        },
        order: [['updatedAt', 'DESC']],
        limit: Number(data.limit) || 10,
        offset: Number(data.offset) || 0,
        distinct: true,
      });
      // 根据返回结果查找点赞的人和博客信息
      for (let i = 0; i < res.rows.length; i++) {
        const Bres = await Blog.findOne({
          where: {
            id: res.rows[i].blogId,
            projectId: data.projectId,
          },
          attributes: {
            exclude: ['id', 'createdAt', 'updatedAt', 'deletedAt'],
          },
        });
        // 博客信息
        if (Bres) {
          res.rows[i].dataValues.Blog = Bres.dataValues;
        }
        // 点赞的人
        const LRes = await LikeBlog.findAndCountAll({
          where: {
            blogId: res.rows[i].blogId,
          },
          attributes: ['likeUserId'],
        });
        res.rows[i].dataValues.LikeBlog = LRes.dataValues;
      }
      return res;
    }
  }
  return BlogService;
};
